package com.koron.css2.newProjectCenter.impl;

import com.koron.css2.ServerInterface;
import com.koron.css2.baseConfig.mapper.MeterBoreMapper;
import com.koron.css2.clientCenter.bean.AccountInfoBean;
import com.koron.css2.clientCenter.bean.CtmInfoBean;
import com.koron.css2.clientCenter.bean.UserBean;
import com.koron.css2.clientCenter.mapper.AccountInfoMapper;
import com.koron.css2.clientCenter.mapper.CtmInfoMapper;
import com.koron.css2.clientCenter.mapper.UserInfoMapper;
import com.koron.css2.clientCenter.queryBean.UserInfoQueryBean;
import com.koron.css2.meterService.dto.MsInfoDto;
import com.koron.css2.meterService.mapper.MsInfoMapper;
import com.koron.css2.newProjectCenter.bean.PjInfoBean;
import com.koron.css2.newProjectCenter.bean.PjMeter;
import com.koron.css2.newProjectCenter.bean.query.PjMeterQuery;
import com.koron.css2.newProjectCenter.mapper.PjInfoMapper;
import com.koron.css2.newProjectCenter.mapper.PjMeterMapper;
import com.koron.css2.newProjectCenter.service.PjInfoService;
import com.koron.css2.serviceManage.bean.RequestBean;
import com.koron.css2.serviceManage.bean.UserInfoBean;
import com.koron.css2.serviceManage.mapper.UserDiscountMapper;
import com.koron.css2.serviceManage.mapper.UserMixtureMapper;
import com.koron.css2.serviceManage.utils.JsonUtils;
import com.koron.util.Constant;
import com.koron.util.Tools;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.swan.bean.MessageBean;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 工程管理-批量保存水表数据
 * 1. 删除原有pjMeter
 * 2. 删除原有userInfoTemp
 * 3. 批量新增userInfoTemp
 * 4. 批量新增pjMeter
 */
public class PjMeterBatchInsert implements ServerInterface {
    private static final String PJ_TYPE_NAME = "水表扩缩";

    private static Logger logger = LoggerFactory.getLogger(ServerInterface.class);

    @Override
    public MessageBean<?> exec(SessionFactory factory, UserInfoBean userInfo, RequestBean req) {
        try {
            List<PjMeter> objectList = JsonUtils.objectToList(req.getData(), PjMeter.class);
            List<String> userInfoTempIdList = new ArrayList<>();
            String consultId = "";
            Set<String> constGroup = new HashSet<>();
            List<PjMeter> pjMeterList = new ArrayList<>();
            if (Objects.isNull(objectList) || objectList.size() <= 0) {
                throw new RuntimeException("水表信息不能为空");
            }

            PjMeterMapper pjMeterMapper = factory.getMapper(PjMeterMapper.class);
            UserMixtureMapper userMixtureMapper = factory.getMapper(UserMixtureMapper.class);
            UserDiscountMapper userDiscountMapper = factory.getMapper(UserDiscountMapper.class);
            CtmInfoMapper ctmInfoMapper = factory.getMapper(CtmInfoMapper.class);
            AccountInfoMapper accountInfoMapper = factory.getMapper(AccountInfoMapper.class);
            UserInfoMapper userInfoMapper = factory.getMapper(UserInfoMapper.class);
            PjInfoMapper pjInfoMapper = factory.getMapper(PjInfoMapper.class);

            // 获取工程类型
            String pjType = pjInfoMapper.getPjType(objectList.get(0).getConsultId());
            Map<String, String> ppt = Tools.mapDicByCode(factory, "PPT");
            // 获取原用户id
            String oldUserId = objectList.get(0).getUserInfo().getId();

            for (int i = 0; i < objectList.size() - 1; i++) {
                MsInfoDto msInfo = objectList.get(i).getMsInfo();
                if (msInfo != null) {
                    for (int j = (i + 1); j < objectList.size(); j++) {
                        MsInfoDto msInfo2 = objectList.get(j).getMsInfo();
                        if (msInfo2 != null && StringUtils.isNotBlank(msInfo.getFactoryNo()) && StringUtils.isNotBlank(msInfo2.getFactoryNo()) && Objects.equals(msInfo.getFactoryNo(), msInfo2.getFactoryNo())) {
                            return MessageBean.create(Constant.MESSAGE_INT_FAIL, "表身码：" + msInfo.getFactoryNo() + "存在重复", null);
                        }
                    }
                }
            }
            PjInfoBean pjInfoBean = null;
            // 预算编制以后的流程节点
            List<String> installAfterList = new ArrayList<>();
            addProcessList(installAfterList);
            for (PjMeter pjMeter : objectList) {
                MsInfoDto msInfo = pjMeter.getMsInfo();
                UserBean userTemp = pjMeter.getUserInfo();
                // 获取流程节点
                String processState = pjInfoMapper.getProcessState(pjMeter.getConsultId());
                // 水表扩缩旧表底码不可小于上期抄码
                if (PJ_TYPE_NAME.equals(ppt.get(pjType)) && installAfterList.contains(processState)) {
                    // 检查旧表底码
                    UserBean oldUserInfo = userInfoMapper.getUserInfoByUserNo(userTemp.getUserNo(), 1);
                    int oldLastReadingNum = userTemp.getOldLastReadingNum() == null ? 0 : userTemp.getOldLastReadingNum();
                    if (oldLastReadingNum < oldUserInfo.getLastReadingNum()) {
                        throw new Exception("旧表止码不可小于上期抄码！");
                    }
                }
                if (pjInfoBean == null) {
                    pjInfoBean = pjInfoMapper.selectById(pjMeter.getConsultId());
                    Objects.requireNonNull(pjInfoBean, "单据信息不存在，请先保存单据");
                }
                if (pjMeter.getUserInfo() != null) {
                    pjMeter.getUserInfo().setBusinessArea(pjInfoBean.getBusinessArea());
                }
                if (msInfo != null && StringUtils.isNotEmpty(msInfo.getFactoryNo())) {
                    pjMeter.setInstallStatus(1);
                    pjMeter.setInstallDate(new Date());
                    pjMeter.setLastModifyDate(new Date());
                } else {
                    pjMeter.setInstallStatus(0);
                }
                consultId = pjMeter.getConsultId();
                userInfoTempIdList.add(pjMeter.getUserInfoTempId());
                pjMeterList.add(pjMeter);

                if (userTemp != null && StringUtils.isNotBlank(userTemp.getMeterBuilder())) {
                    constGroup.add(userTemp.getMeterBuilder());
                }
            }

            // 保存施工人员至主表
            if (constGroup.size() > 0) {
                pjInfoBean.setUpdateInfo(userInfo);
                pjInfoBean.setConstGroup(constGroup.stream().collect(Collectors.joining(",")));
                pjInfoMapper.saveBuild(pjInfoBean);
            }
            // 删除所有pjMeter
            PjMeterQuery pjMeterQuery = new PjMeterQuery();
            pjMeterQuery.setConsultId(consultId);
            List<PjMeter> oldPjMeterList = pjMeterMapper.getList(pjMeterQuery);
            MsInfoMapper msInfoMapper = factory.getMapper(MsInfoMapper.class);
            for (PjMeter pjMeter : oldPjMeterList) {
                if (StringUtils.isNotEmpty(pjMeter.getMsInfoId())) {
                    msInfoMapper.updateMsInfoStatusById(pjMeter.getMsInfoId(), 1); // 之前的水表改为在库
                }
            }
            pjMeterMapper.delete(pjMeterQuery);
            // 删除所有userInfoTemp
            if (userInfoTempIdList != null && userInfoTempIdList.size() > 0) {
                UserInfoQueryBean userInfoQueryBean = new UserInfoQueryBean();
                userInfoQueryBean.setIdList(userInfoTempIdList);
                userInfoMapper.batchDelete(userInfoQueryBean, UserBean.USERTEMP);
            }
            // 将工程登记时的 客户信息以及账户信息查询出来
            CtmInfoBean ctmInfoBean = ctmInfoMapper.getCtmInfoById(pjInfoBean.getUserCtmTempId(), CtmInfoBean.CTMTEMP);
            AccountInfoBean accountInfoBean = accountInfoMapper.getAccountInfoById(pjInfoBean.getUserAccountTempId(), AccountInfoBean.ACCOUNTTEMP);
            PjMeter firstMeter = pjMeterList.get(0);
            // 如果第一个水表客户信息信息为空
            if (Objects.isNull(firstMeter.getCtmInfo())){
                // 将工程登记时的 客户信息以及账户信息赋值到第一个水表信息
                firstMeter.setCtmInfo(ctmInfoBean);
                firstMeter.setAccountInfo(accountInfoBean);
            }
            // 循环水表列表
            for (int i = 0; i < pjMeterList.size(); i++) {
                try {
                    PjMeter pjMeter = pjMeterList.get(i);
                    UserBean user = pjMeter.getUserInfo();
                    // 保存用户信息，存在则修改，不存在则插入 返回用户编号
                    String userNo = savePjMeterAndReturnUserNo(factory, userInfo, userMixtureMapper, userDiscountMapper, ctmInfoBean, accountInfoBean, pjMeter);
                    // 如果该水表的客户信息为空，则表示是新增水表，需要已工程登记时的 客户信息为基础进行插入
                    if (Objects.isNull(pjMeter.getCtmInfo())) {
                        ctmInfoBean.setId(null);
                        // 水表明细中如果修改了客户名称，则需要同步修改 客户表的 客户名称字段
                        if (StringUtils.isNotBlank(user.getCtmName())){
                            ctmInfoBean.setCtmName(user.getCtmName());
                        }
                        // 保存客户信息，如果客户信息存在则修改 不存在则插入 返回主键ID
                        String tempCtmId = saveCtm(factory, userInfo, ctmInfoBean);
                        // 将客户信息的主键ID 赋值到水表明细
                        pjMeter.setUserCtmTempId(tempCtmId);
                    }else {
                        // 水表明细中如果修改了客户名称，则需要同步修改 客户表的 客户名称字段
                        if (StringUtils.isNotBlank(user.getCtmName())){
                            pjMeter.getCtmInfo().setCtmName(user.getCtmName());
                        }
                        // 修改客户信息
                        saveCtm(factory, userInfo, pjMeter.getCtmInfo());
                        // 将客户信息的主键ID 赋值到水表明细
                        pjMeter.setUserCtmTempId(pjMeter.getCtmInfo().getId());
                    }

                    // 如果账户信息为空
                    if (Objects.isNull(pjMeter.getAccountInfo())) {
                        accountInfoBean.setId(null);
                        String tempAccountId = saveAccount(factory, userInfo, accountInfoBean);
                        pjMeter.setUserAccountTempId(tempAccountId);
                    }else {
                        // 修改账户信息
                        saveAccount(factory, userInfo, pjMeter.getAccountInfo());
                        // 如果账号信息不为空，将临时表的账户ID设置到水表明细ID
                        pjMeter.setUserAccountTempId(pjMeter.getAccountInfo().getId());
                    }
                } catch (Exception e) {
                    throw new RuntimeException("第" + (i +1)+ "行：" + e.getMessage());
                }
            }
            for (PjMeter pjMeter : objectList) {
                if (pjMeter.getMsInfo() != null) {
                    msInfoMapper.updateMsInfoStatus(pjMeter.getMsInfo().getMeterNo(), 2); // 新的水表改为在用
                }
            }
            // 8. 批量新增pjMeter
            pjMeterMapper.batchInsert(pjMeterList);
            int meterNum = pjMeterList.size();//水表个数
            List<String> boreList = pjMeterList.stream().map(x -> x.getMsInfo().getMeterBore()).collect(Collectors.toList());
            MeterBoreMapper boreMapper = factory.getMapper(MeterBoreMapper.class);
            String maxBore = boreMapper.getMaxBoreIdByIds(boreList);//水表口径
            pjInfoMapper.updateBoreAndMeterNum(consultId, meterNum, maxBore);
            // 9. 返回结果
            return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "批量保存水表数据成功", null);
        } catch (Exception e) {
            logger.error("批量保存水表数据失败" + e);
            return MessageBean.create(Constant.MESSAGE_INT_FAIL, "批量保存水表数据失败：" + e.getMessage(), null);
        }
    }

    /**
     * 施工分派以后的节点信息
     */
    private static void addProcessList(List<String> installAfterList) {
        installAfterList.add(PjInfoService.BUILD);
        installAfterList.add(PjInfoService.INSTALL_BUILD);
        installAfterList.add(PjInfoService.REGISTER_ACCOUNT);
        installAfterList.add(PjInfoService.REGISTER_ACCOUNT_APPROVAL);
        installAfterList.add(PjInfoService.INVITATION_CHECK);
        installAfterList.add(PjInfoService.INVITATION_CHECK_ACCEPT);
        installAfterList.add(PjInfoService.CHECK);
        installAfterList.add(PjInfoService.DATA_ARCHIVE);
    }

    private String savePjMeterAndReturnUserNo(SessionFactory factory, UserInfoBean userInfo, UserMixtureMapper userMixtureMapper, UserDiscountMapper userDiscountMapper, CtmInfoBean ctmInfoBean, AccountInfoBean accountInfoBean, PjMeter pjMeter) {
        String userNo;
        // 1. pjMeter: id,createAccount,createTime,createName,tenantId
        pjMeter.setCreateInfo(userInfo);
        // 2. userNo; 保存userInfoTemp;兼容前端传入混合数据时，部分数据已有id的情况
        UserBean userBean = pjMeter.getUserInfo();
        if (StringUtils.isNotEmpty(userBean.getId())) {
            userBean.setId("");
        }
        PjSave pjSave = new PjSave();
        userNo = pjSave.saveMeterUserInfoTemp(factory, userInfo, pjMeter, ctmInfoBean,
                accountInfoBean, pjMeter.getMsInfo());
        // 3. 保存userMixture
        pjSave.saveMeterUserMixture(userMixtureMapper, userInfo, pjMeter, userNo);
        // 4. 保存userDiscount
        pjSave.saveMeterUserDiscount(userDiscountMapper, userInfo, pjMeter, userNo);
        // 5. 返回userNo
        return userNo;
    }

    public String saveCtm(SessionFactory factory, UserInfoBean userInfo, CtmInfoBean ctmInfoBean) {
        if (StringUtils.isBlank(ctmInfoBean.getCreditLevel())) {
            ctmInfoBean.setCreditLevel("1");
        }
        if (StringUtils.isBlank(ctmInfoBean.getId())) {
            //新增
            ctmInfoBean.setId(Tools.getObjectId());
            ctmInfoBean.setCreateName(userInfo.getUserInfo().getName());
            ctmInfoBean.setCreateAccount(userInfo.getUserInfo().getAcount());
            ctmInfoBean.setCtmNo(Tools.getCtmNo(factory, userInfo.getCurWaterCode()));
            // 将客户地址赋给 客户结构化地址详情字段
            ctmInfoBean.setClientAddrDetail(ctmInfoBean.getCtmAddr());
            // 将客户地址赋给 客户结构化地址字段
            ctmInfoBean.setClientAddr(ctmInfoBean.getCtmAddr());
            factory.getMapper(CtmInfoMapper.class).ctmInfoAdd(ctmInfoBean, 2);
        } else {
            // 将客户地址赋给 客户结构化地址详情字段
            ctmInfoBean.setClientAddrDetail(ctmInfoBean.getCtmAddr());
            // 将客户地址赋给 客户结构化地址字段
            ctmInfoBean.setClientAddr(ctmInfoBean.getCtmAddr());
            ctmInfoBean.setUpdateName(userInfo.getUserInfo().getName());
            ctmInfoBean.setUpdateAccount(userInfo.getUserInfo().getAcount());
            factory.getMapper(CtmInfoMapper.class).ctmInfoUpdate(ctmInfoBean, 2);
        }
        return ctmInfoBean.getId();
    }

    /**
     * 保存账户信息
     *
     * @param factory
     * @param userInfo
     * @param accountInfoBean
     */
    public String saveAccount(SessionFactory factory, UserInfoBean userInfo, AccountInfoBean accountInfoBean) {
        if (StringUtils.isBlank(accountInfoBean.getId())) {
            //新增
            accountInfoBean.setId(Tools.getObjectId());
            accountInfoBean.setCreateName(userInfo.getUserInfo().getName());
            accountInfoBean.setCreateAccount(userInfo.getUserInfo().getAcount());
            accountInfoBean.setAccountNo(Tools.getAccountNo(factory, userInfo.getCurWaterCode()));
            factory.getMapper(AccountInfoMapper.class).accountInfoAdd(accountInfoBean, 2);
        } else {
            //修改
            accountInfoBean.setUpdateName(userInfo.getUserInfo().getName());
            accountInfoBean.setUpdateAccount(userInfo.getUserInfo().getAcount());
            factory.getMapper(AccountInfoMapper.class).accountInfoUpdate(accountInfoBean, 2);
        }
        return accountInfoBean.getId();
    }
}
